<?php

class ClassStructure_UtilityFunctions {
    
    
    
    static public function getObjectSignature($obj) {

        $str_class   = self::getClassSignature($obj);
        $str_mixins  = self::getMixinSignatures($obj);
        $str_methods = self::getMethodSignatures($obj);
    
        $str = $str_class . "{\n\n$str_mixins\n$str_methods\n}\n";
        
        return $str;
    }
    
    static public function getClassSignature($obj) {
        
        $str_class_real = get_class($obj);
        
        $str_class = $obj->__getClass();
        $str_parent = $obj->__getParentClass();
        
        $arr_interfaces = class_implements($str_class);
        
        $str_interfaces = '';
        if(!empty($arr_interfaces)) {
            $str_interfaces = "\n   implements " . implode(', ', $arr_interfaces); 
        }
        
        $str_mixins = '';
        if($obj instanceof ClassStructure_Mixin) {
            $arr_mixins = $obj->__getMixins();
            
            $arr_mixin_classes = array();
            foreach($arr_mixins as $str_mixin_key => $obj_mixin) {
                $str_mixin_class = get_class($obj_mixin);
                $arr_mixin_classes[$str_mixin_class] = $str_mixin_class;
            }
            
            $str_mixins = "\n   delegates " . implode(', ', $arr_mixin_classes); 
        }
        
        $str_weaved = '';
        if($obj instanceof ClassStructure_Weaved) {
            $str_weaved = 'class ' . get_class($obj) . " weaves\n";
        }
        
        $str = $str_weaved . "class $str_class\n   extends $str_parent $str_interfaces $str_mixins\n";
        
        return $str;
    }
    
    static public function getMethodSignatures($obj) {
        
        $str = '';
        
        $arr_methods = $obj->__getMethodSignatures();
        ksort($arr_methods);
        foreach($arr_methods as $str_method => $str_signature) {
            $str .= $str_signature . ";\n";
        }
        
        return $str;
    }
    
    static public function getMixinSignatures($obj) {
        
        $str = '';
        
        if($obj instanceof ClassStructure_Mixin) {
            $arr_mixins = $obj->__getMixins();
            
            $arr_mixin_keys = array_keys($arr_mixins);
            
            $str_padding = 0;
            foreach($arr_mixin_keys as $str_key) {
                $str_length = strlen($str_key);
                if($str_length > $str_padding) {
                    $str_padding = $str_length;
                }
            }
            
            foreach($arr_mixins as $str_mixin_key => $obj_mixin) {
                $str .= '       mixin $' . str_pad($str_mixin_key, $str_padding, ' ') . ' => ' . get_class($obj_mixin) . '();' . "\n";
            }
        }
        
        return $str;
        
    }
    
    static public function getAdviceSignature($obj, $str_method) {
        
        $str = null;
        
        if($obj instanceof ClassStructure_Weaved) {
            $str = $obj->__getAdviceSignature($str_method);
        }
        
        return $str;
    }
    
    static public function testClassRelationshipsAgainst($obj, $mix_tests) {
        
        if(!empty($mix_tests)) {
            
            $arr_tests = is_array($mix_tests) ? $mix_tests : array($mix_tests);
            
            echo 'Subclass Tests:' . "\n";
            $arr_subclasses = $arr_tests;
            
            foreach($arr_subclasses as $str_subclass) {
                $bln = $obj->__isSubclassOf($str_subclass);
                $bln = $bln ? 'is' : 'is not';
                echo '$obj ' . $bln . ' a subclass of ' . $str_subclass . '.' . "\n";
            }
            echo "\n";
            
            echo 'Instance Tests:' . "\n";
            $arr_instances = $arr_tests;
            
            foreach($arr_instances as $str_instance) {
                $bln = $obj->__isInstanceOf($str_instance);
                $bln = $bln ? 'is' : 'is not';
                echo '$obj ' . $bln . ' an instance of ' . $str_instance . '.' . "\n";
            }
            echo "\n";
        
        }
        
    }
    
}
